#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define LEFT "["
#define RIGHT "]"
#define DELIM " "
#define LABLE "#"
#define LINE_SIZE 1024
#define ARGC_SIZE 32
#define QUIT_CODE 44
int lastcode =0;
char commandline[LINE_SIZE];
extern char**environ;
  char* argv[ARGC_SIZE];
  char pwd[LINE_SIZE];//存储当前工作路径的数组
  char myenv[LINE_SIZE];//存储环境变量的数组
const char* getuser()
{
  return getenv("USER");
}
const char*gethostname()
{
  return getenv("HOSTNAME");
}
void getpwd()
{
  getcwd(pwd,sizeof(pwd));
}
void interact(char * cline,int size)//交互，获取字符串并存放
{
  getpwd();
  printf(LEFT"%s@%s %s"RIGHT" "LABLE,getuser(),gethostname(),pwd);
  char*s=fgets(cline,size,stdin);//从stdin获取字符并存放在commandline
  assert(s!=NULL);
  (void)s;//避免报错
  cline[strlen(cline)-1]='\0';//"abcd\n\0" '\n'不要
}
int splitstring(char*cline,char*_argv[])
{
  int i=0;

  _argv[i++]=strtok(cline,DELIM);
  while(_argv[i++]=strtok(NULL,DELIM));
   // if(i==ARGC_SIZE)break;
  return i-1;//返回命令行+参数个数
}
void normalexecute(char*_argv[])
{
pid_t id=fork();
if(id<0)
{
  perror("fork");
  return;
}
else if(id==0)
{
  //child
  execvp(_argv[0],_argv);
  exit(QUIT_CODE);//创建失败返回退出码
}
else{
  //parent
  int status=0;
  pid_t ret_id=waitpid(id,&status,0);
  if(ret_id==id)//等到子进程
  {
     lastcode=WEXITSTATUS(status);
  }
}
}
int Buildcommand(char*_argv[],int _argc)
{
  if(_argc==2&&strcmp(_argv[0],"cd")==0)
  {
    chdir(_argv[1]);//更改当前工作路径
    getpwd();//获取当前工作路径存储在pwd数组中
    sprintf(getenv("PWD"),"%s",pwd);
    return 1;
  }
  else if(_argc==2&&strcmp(_argv[0],"export")==0)
  {
    strcpy(myenv,_argv[1]);//导出前拷贝
    putenv(myenv);
    return 1;
  }
  else if(_argc==2&&strcmp(_argv[0],"echo")==0)
  {
    if(strcmp(_argv[1],"$?")==0)
    {
      printf("%d\n",lastcode);
      lastcode =0;
    }
    else if(*_argv[1]=='$')
    {
      char*s=getenv(_argv[1]+1);
      if(s)printf("%s\n",s);
    }
    else{
      //直接打印
      printf("%s\n",_argv[1]);
    }
    return 1;
  }
  if(strcmp(_argv[0],"ls")==0)
  {
    _argv[_argc++]="--color";
    _argv[_argc]=NULL;
  }
  return 0;
}
int main()
{
 int flag=0;
  while(!flag)//死循环
  {
  interact(commandline,sizeof(commandline));//2.交互
 // printf("%s\n",commandline);
 int argc= splitstring(commandline,argv);//3.解析字符串
 if(argc==0)continue;

 //4.判断命令//对内建命令的处理：
int n= Buildcommand(argv,argc);
 
 //5.普通命令执行
 if(!n)normalexecute(argv);

// for(int i=0;i<ARGC_SIZE;i++)
// {
//   printf("[%d]:%s\n",i,argv[i]);
// }
  }
  return 0;
}
